package com.cxx.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cxx.admin.dao.BlogDao;
import com.cxx.admin.service.BlogManageService;
import com.cxx.admin.util.BlogUtils;
import com.cxx.admin.dto.blog.BlogCategoryDto;
import com.cxx.admin.dto.blog.BlogDto;
import com.cxx.admin.dto.blog.BlogVisitDto;
import com.cxx.admin.entity.Blog;
import com.cxx.admin.entity.BlogCategory;
import com.cxx.admin.entity.BlogContent;
import com.cxx.admin.mapper.BlogCategoryMapper;
import com.cxx.admin.mapper.BlogContentMapper;
import com.cxx.admin.mapper.BlogMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
public class BlogManageServiceImpl implements BlogManageService {
    @Resource
    private BlogDao blogDao;

    @Resource
    private BlogMapper blogMapper;

    @Resource
    private BlogCategoryMapper categoryMapper;

    @Resource
    private BlogContentMapper contentMapper;

    @Override
    public IPage<BlogDto> queryBlogByPage(Integer currentPage, Integer pageSize) {
        return blogDao.queryBlogByPage(new Page<>(currentPage, pageSize));
    }

    @Override
    public BlogDto queryBlogById(Long id) {
        return blogDao.queryBlogById(id);
    }

    @Override
    public List<BlogCategoryDto> queryBlogCategory() {
        return blogDao.queryBlogCategory();
    }

    @Transactional
    @Override
    public Boolean addBlog(BlogDto blogDto) {
        // 1. 新增博客基本信息
        Blog blog = saveOrUpdateNewBlog(blogDto);
        // 2. 新增博客内容信息
        blog.setContentId(addBlogContent(blogDto.getContent()));
        // 3. 插入数据库
        return blogMapper.insert(blog) == 1;
    }

    @Transactional
    @Override
    public Boolean updateBlog(Long id, BlogDto blogDto) {
        Blog blog = saveOrUpdateNewBlog(blogDto);
        blog.setId(id);
        // 1. 更新博客内容信息
        updateBlogContent(getBlogById(id).getContentId(), blogDto.getContent());
        // 2. 校验是否删除博客类别
        deleteBlogCategory(getBlogById(id).getCategoryId());
        // 3. 更新数据库
        return blogMapper.updateById(blog) == 1;
    }

    @Transactional
    @Override
    public Boolean deleteBlog(Long id) {
        // 1. 删除博客类别
        deleteBlogCategory(getBlogById(id).getCategoryId());
        // 2. 删除博客内容
        contentMapper.deleteById(getBlogById(id).getContentId());
        // 3. 删除博客
        return blogMapper.deleteById(id) == 1;
    }

    @Override
    public IPage<BlogVisitDto> queryBlogVisit(Integer currentPage, Integer pageSize) {
        return blogDao.queryBlogVisit(new Page<>(currentPage, pageSize));
    }

    /**
     * 通过博客id获取博客
     * @param id id
     * @return 博客
     */
    private Blog getBlogById(Long id) {
        Blog blog = blogMapper.selectById(id);

        if (Objects.isNull(blog)) {
            throw new RuntimeException("暂无该博客");
        }

        return blog;
    }

    /**
     * 增加/更新 博客
     * @param blogDto 前端传入的博客内容
     * @return 博客
     */
    private Blog saveOrUpdateNewBlog(BlogDto blogDto) {
        Blog newBlog = new Blog();

        // 设置博客基础信息
        newBlog.setTitle(blogDto.getTitle());
        newBlog.setTopValue(blogDto.getTopValue());
        newBlog.setIsGreat(blogDto.getIsGreat());

        // 设置博客类别
        newBlog.setCategoryId(saveOrUpdateBlogCategory(blogDto.getCategory()));

        // 设置博客内容
        newBlog.setSummary(BlogUtils.getBlogSummary(blogDto.getContent()));

        // 设置博客字数统计
        Integer wordCount = BlogUtils.getWordCount(blogDto.getContent());
        newBlog.setWordCount(wordCount);
        newBlog.setReadDuration(BlogUtils.getReadDuration(wordCount));

        return newBlog;
    }

    /**
     * 设置博客类别
     * @param category 类别
     * @return 类别id
     */
    private Long saveOrUpdateBlogCategory(String category) {
        // 1. 查找类别是否存在
        LambdaQueryWrapper<BlogCategory> queryWrapper = new LambdaQueryWrapper<>();
        BlogCategory blogCategory = categoryMapper.selectOne(queryWrapper.eq(BlogCategory::getName, category));

        // 2. 如果存在则返回id 否则需要新增类别
        if (Objects.isNull(blogCategory)) {
            BlogCategory newBlogCategory = new BlogCategory();
            newBlogCategory.setName(category);
            categoryMapper.insert(newBlogCategory);
            return newBlogCategory.getId();
        } else {
            return blogCategory.getId();
        }
    }

    /**
     * 判断是否需要删除博客类别
     * @param categoryId 博客类别id
     */
    private void deleteBlogCategory(Long categoryId) {
        LambdaQueryWrapper<Blog> queryWrapper = new LambdaQueryWrapper<>();
        if (!blogMapper.exists(queryWrapper.eq(Blog::getCategoryId, categoryId))) {
            // 如果没有该类别的博客 则删除博客类别
            categoryMapper.deleteById(categoryId);
        }
    }

    /**
     * 新增博客内容
     * @param content 博客内容
     * @return 博客内容id
     */
    private Long addBlogContent(String content) {
        BlogContent blogContent = new BlogContent();
        blogContent.setContent(content);
        contentMapper.insert(blogContent);

        return blogContent.getId();
    }

    /**
     * 更新博客内容
     * @param contentId 博客内容id
     * @param content   博客内容
     */
    private void updateBlogContent(Long contentId, String content) {
        BlogContent blogContent = new BlogContent();
        blogContent.setContent(content);
        blogContent.setId(contentId);
        contentMapper.updateById(blogContent);
    }
}
